home *** CD-ROM | disk | FTP | other *** search
- page 96,132
- ;§∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞§
- ;§ §
- ;§ ディレクトリエントリ ソート ユーティリティ §
- ;§ §
- ;§ DSORT.EXE Ver1.30 §
- ;§ §
- ;§ Copyright (C) by 福地 邦雄 1991-1992. All rights reserved. §
- ;§∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞§
- .MODEL SMALL,C
- ;
- public options,usageout,dirlist,dirfind,strcopywild
- extrn sweep:word,sortexec:word,recursive:word,dirgather:word
- extrn dta:dword,srchname:dword,namebuff:dword,namebuffsiz:word
- extrn dirtype:word,fattype:word,attribute:word,clustcount:word
- extrn driveno:word,clustsize:word
- extrn fatbuff:word,dirbuff:word,sortbuff:word,sortcount:word
- extrn drvinf:byte,clustsect:word,subsearch:word
- extrn sortfuncs:word,subchain:word,wildcard:byte,pathbuff:byte
- extrn usagemsg:byte,_msgsize:abs
- extrn abort:near
- extrn errorno:word
- ;
- PUBLIC setsortfunc,setsortobj,cmpdummy,cmpdirf,cmpfull,cmpname
- PUBLIC cmpextn,cmpsize,cmpdate,cmptime,strncmp,chrtypes,pathsep
- ;
- REVERSE equ 1
- NORMAL equ 0
- TAIL equ 1
- HEAD equ 0
- YES equ 1
- NO equ 0
- TAB equ 9
- CR equ 0dh
- LF equ 0ah
- DEFAULT equ 031h
- ARCHIVE equ 020h
- SUBDIR equ 010h
- VOLUME equ 008h
- HIDDEN equ 004h
- SYSTEM equ 002h
- RDONLY equ 001h
- ;
- .code
- ;
- ;------------------------------------------------------------------------------
- ;
- ; options
- ; オプション指定の評価とディレクトリのリストを取る
- ;
- ; TYPE near call
- ; IN AX アーギュメント数
- ; SS:BP アーギュメントポインタリストの先頭アドレス
- ; OUT 特になし
- ; 保存レジスタ ds
- ;
- ;------------------------------------------------------------------------------
- ;
- options proc
- ;
- cld
- push ax
- mov ah,2fh ; Disk Transfer Address 取得
- int 21h
- lea bx,[bx+1eh] ; DTAのファイル名オフセット
- mov word ptr dta,bx
- mov word ptr dta+2,es
- pop bx
- mov sortfuncs,offset _text:cmpdummy ; ダミーのソート比較関数セット
- mov word ptr sortfuncs+2,NORMAL
- mov si,offset sortfuncs+4
- mov attribute,DEFAULT ; ソート対象属性のデフォルトセット
- @do until
- les di,[bp]
- @cbegin
- @case (byte ptr es:[di],=,'-'),S
- call setsortfunc
- @case (byte ptr es:[di],=,'+'),S
- call setsortobj
- @other
- mov word ptr srchname,di ; ディレクトリ名リストの作成
- mov word ptr srchname+2,es
- call dirlist
- @cend
- add bp,4 ; 次のアーギュメントへ
- dec bx
- @doend (zf,on)
- @if (si,=,offset sortfuncs+4)
- mov word ptr [si],offset cmpfull ; デフォルトの比較関数セット
- mov word ptr [si+2],NORMAL
- lea si,[si+4]
- @ifend
- not attribute ; ソート対象属性を反転させたものを使う
- mov word ptr [si],0 ; ソート比較関数リストのエンドマーク
- les di,namebuff ; ディレクトリ名リストのエンドマーク
- mov word ptr es:[di],0
- @if (word ptr es:[0],=,0)
- jmp usageout ; ディレクトリ無しの時、ヘルプ表示
- @ifend
- ret
- ;
- options endp
- ;
- ;------------------------------------------------------------------------------
- ;
- ; usageout
- ; ヘルプメッセージを表示して終了
- ;
- ; TYPE near call
- ; IN なし
- ; OUT なし
- ; 保存レジスタ なし
- ;
- ;------------------------------------------------------------------------------
- ;
- usageout proc
- ;
- mov errorno,1
- mov dx,offset usagemsg
- mov cx,_msgsize
- jmp abort
- ;
- usageout endp
- ;
- ;------------------------------------------------------------------------------
- ;
- ; setsortfunc
- ; ソート機能指定オプションの評価と、比較関数リストの作成
- ;
- ; TYPE near call
- ; IN AL アーギュメント文字
- ; DS:SI 比較関数リストアドレス
- ; OUT SI += 4
- ; 保存レジスタ bx,cx,dx,di,bp,ds,es
- ;
- ;------------------------------------------------------------------------------
- ;
- setsortfunc proc
- ;
- inc di
- @do repeat
- mov al,es:[di]
- inc di
- @if (al,=,0)
- @doexit
- @ifend
- @if (al,>=,'a'),S ; 昇順
- mov word ptr [si+2],NORMAL
- sub al,'a'-'A'
- @else ; 降順
- mov word ptr [si+2],REVERSE
- @ifend
- @cbegin
- @case (al,=,'D'),S ; 最終更新日付
- mov ax,offset _text:cmpdate
- @case (al,=,'E'),S ; 拡張子 3バイト
- mov ax,offset _text:cmpextn
- @case (al,=,'F'),S ; フルネーム 11バイト
- mov ax,offset _text:cmpfull
- @case (al,=,'N'),S ; ファイル名 8バイト
- mov ax,offset _text:cmpname
- @case (al,=,'S'),S ; ファイルサイズ
- mov ax,offset _text:cmpsize
- @case (al,=,'T'),S ; 最終更新時刻
- mov ax,offset _text:cmptime
- @other
- jmp usageout
- @cend
- mov [si],ax
- lea si,[si+4]
- @doend
- ret
- ;
- setsortfunc endp
- ;
- ;------------------------------------------------------------------------------
- ;
- ; setsortobj
- ; ソート対象選択オプション評価
- ;
- ; TYPE near call
- ; IN AL アーギュメント文字
- ; OUT なし
- ; 保存レジスタ AX以外
- ;
- ;------------------------------------------------------------------------------
- ;
- setsortobj proc
- ;
- inc di
- @do repeat
- mov al,es:[di]
- inc di
- @if (al,=,0)
- @doexit
- @ifend
- @if (al,>=,'a'),S ; 先頭に
- mov dirgather,HEAD
- sub al,'a'-'A'
- @else ; 末尾に
- mov dirgather,TAIL
- @ifend
- @cbegin
- @case (al,=,'G'),S ; ディレクトリの扱い
- mov sortfuncs,offset _text:cmpdirf
- mov ax,dirgather
- mov sortfuncs+2,ax
- @case (al,=,'T'),S ; 再帰呼び出し
- mov recursive,YES
- @case (al,=,'N'),S ; ソート無し
- mov sortexec,NO
- @case (al,=,'F'),S ; 掃き寄せ無し
- mov sweep,NO
- @case (al,=,'A'),S ; アーカイブ属性
- xor attribute,ARCHIVE
- @case (al,=,'D'),S ; ディレクトリ
- xor attribute,SUBDIR
- @case (al,=,'V'),S ; ボリュームラベル
- xor attribute,VOLUME
- @case (al,=,'S'),S ; システムファイル
- xor attribute,SYSTEM
- @case (al,=,'H'),S ; 隠しファイル
- xor attribute,HIDDEN
- @case (al,=,'R'),S ; 読み出しのみ可能
- xor attribute,RDONLY
- @other
- jmp usageout
- @cend
- @doend
- ret
- ;
- setsortobj endp
- ;
- ;------------------------------------------------------------------------------
- ;
- ; cmpdummy
- ; ダミー比較ルーチン 必ず = で終了
- ;
- ; TYPE near call
- ; IN なし
- ; OUT AX=0 ZERO FLAG=1
- ; 保存レジスタ AX以外
- ;
- ;------------------------------------------------------------------------------
- ;
- cmpdummy proc
- ;
- xor ax,ax
- ret
- ;
- cmpdummy endp
- ;
- ;------------------------------------------------------------------------------
- ;
- ; cmpdirf
- ; ディレクトリ属性比較
- ;
- ; TYPE near call
- ; IN DS:0 エントリ1アドレス
- ; DX:0 エントリ2アドレス
- ; OUT AX ディレクトリ:通常= -1 通常:ディレクトリ= 1 その他 0
- ; 保存レジスタ AX以外
- ;
- ;------------------------------------------------------------------------------
- ;
- cmpdirf proc
- ;
- mov al,ds:[0bh] ; 属性バイトの取り出し
- push es
- mov es,dx
- mov ah,es:[0bh]
- pop es
- and ax,01010h
- cmp al,ah
- ja dirfhead ; Dir:File
- jb dirftail ; File:Dir
- xor ax,ax ; 同じ属性
- ret
- dirfhead:
- mov ax,-1
- ret
- dirftail:
- mov ax,1
- ret
- ;
- cmpdirf endp
- ;
- ;------------------------------------------------------------------------------
- ;
- ; cmpfull
- ; フルネーム比較
- ;
- ; TYPE near call
- ; IN DS:0 エントリ1アドレス
- ; dx:0 エントリ2アドレス
- ; OUT AX エントリ1<エントリ2= -1 エントリ1=エントリ2= 0 エントリ1>エントリ2= 1
- ; 保存レジスタ bx,dx,bp,ds,es
- ;
- ;------------------------------------------------------------------------------
- ;
- cmpfull proc
- ;
- mov cx,11
- xor si,si
- xor di,di
- call strncmp
- ret
- ;
- cmpfull endp
- ;
- ;------------------------------------------------------------------------------
- ;
- ; cmpname
- ; ファイル名比較
- ;
- ; TYPE near call
- ; IN DS:0 エントリ1アドレス
- ; dx:0 エントリ2アドレス
- ; OUT AX エントリ1<エントリ2= -1 エントリ1=エントリ2= 0 エントリ1>エントリ2= 1
- ; 保存レジスタ bx,dx,bp,ds,es
- ;
- ;------------------------------------------------------------------------------
- ;
- cmpname proc
- ;
- mov cx,8
- xor si,si
- xor di,di
- call strncmp
- ret
- ;
- cmpname endp
- ;
- ;------------------------------------------------------------------------------
- ;
- ; cmpextn
- ; 拡張子比較
- ;
- ; TYPE near call
- ; IN DS:0 エントリ1アドレス
- ; dx:0 エントリ2アドレス
- ; OUT AX エントリ1<エントリ2= -1 エントリ1=エントリ2= 0 エントリ1>エントリ2= 1
- ; 保存レジスタ bx,dx,bp,ds,es
- ;
- ;------------------------------------------------------------------------------
- ;
- cmpextn proc
- ;
- mov si,8 ; 拡張子位置
- mov di,si
- mov cx,3
- call strncmp
- ret
- ;
- cmpextn endp
- ;
- ;------------------------------------------------------------------------------
- ;
- ; cmpsize
- ; ファイルサイズ比較
- ;
- ; TYPE near call
- ; IN DS:0 エントリ1アドレス
- ; DX:0 エントリ2アドレス
- ; OUT AX エントリ1<エントリ2= -1 エントリ1=エントリ2= 0 エントリ1>エントリ2= 1
- ; 保存レジスタ bx,dx,si,di,bp,ds,es
- ;
- ;------------------------------------------------------------------------------
- ;
- cmpsize proc
- ;
- push es
- mov es,dx
- mov ax,es:[1ch] ; エントリ2のファイルサイズ4バイト
- mov cx,es:[1eh]
- pop es
- cmp cx,ds:[1eh] ; エントリ1と比較
- ja sizeabove
- jb sizebelow
- cmp ax,ds:[1ch]
- ja sizeabove
- jb sizebelow
- xor ax,ax
- ret
- sizeabove:
- mov ax,-1
- ret
- sizebelow:
- mov ax,1
- ret
- ;
- cmpsize endp
- ;
- ;------------------------------------------------------------------------------
- ;
- ; cmpdate
- ; 最終更新日付比較
- ;
- ; TYPE near call
- ; IN DS:0 エントリ1アドレス
- ; DX:0 エントリ2アドレス
- ; OUT AX エントリ1<エントリ2= -1 エントリ1=エントリ2= 0 エントリ1>エントリ2= 1
- ; 保存レジスタ bx,dx,si,di,bp,ds,es
- ;
- ;------------------------------------------------------------------------------
- ;
- cmpdate proc
- ;
- mov ax,ds:[18h]
- push es
- mov es,dx
- cmp ax,es:[18h]
- pop es
- ja dateabove
- jb datebelow
- xor ax,ax
- ret
- dateabove:
- mov ax,1
- ret
- datebelow:
- mov ax,-1
- ret
- ;
- cmpdate endp
- ;
- ;------------------------------------------------------------------------------
- ;
- ; cmptime
- ; 最終更新時刻比較
- ;
- ; TYPE near call
- ; IN DS:0 エントリ1アドレス
- ; DX:0 エントリ2アドレス
- ; OUT AX エントリ1<エントリ2= -1 エントリ1=エントリ2= 0 エントリ1>エントリ2= 1
- ; 保存レジスタ bx,dx,si,di,bp,ds,es
- ;
- ;------------------------------------------------------------------------------
- ;
- cmptime proc
- ;
- mov ax,ds:[16h]
- push es
- mov es,dx
- cmp ax,es:[16h]
- pop es
- ja timeabove
- jb timebelow
- xor ax,ax
- ret
- timeabove:
- mov ax,1
- ret
- timebelow:
- mov ax,-1
- ret
- ;
- cmptime endp
- ;
- ;------------------------------------------------------------------------------
- ;
- ; strncmp
- ; 文字列比較 漢字対応 漢字はANKより大きい
- ;
- ; TYPE near call
- ; IN CX 比較サイズ
- ; DS:SI エントリ1アドレス
- ; ES:DI エントリ2アドレス
- ; OUT AX エントリ1<エントリ2= -1 エントリ1=エントリ2= 0 エントリ1>エントリ2= 1
- ; 保存レジスタ bx,dx,si,di,bp,ds,es
- ;
- ;------------------------------------------------------------------------------
- ;
- strncmp proc uses bx es
- ;
- cld
- mov es,dx
- @do until
- dec cx
- mov ax,[si] ; エントリ1 1文字取得
- inc si
- call chrtypes
- @if (zf,off)
- dec cx
- inc si
- @ifend
- ;
- mov bx,ax
- mov ax,es:[di] ; エントリ2 1文字取得
- inc di
- call chrtypes
- @if (zf,off)
- inc di
- @ifend
- cmp bx,ax ; 比較
- ja strabove
- jb strbelow
- or cx,cx
- @doend (zf,on),or,(sf,on)
- ;
- xor ax,ax
- streturn:
- ret
- ;
- strabove:
- mov ax,1
- jmp streturn
- strbelow:
- mov ax,-1
- jmp streturn
- ;
- strncmp endp
- ;
- ;------------------------------------------------------------------------------
- ;
- ; chrtypes
- ; 漢字判定
- ;
- ; TYPE near call
- ; IN AX 文字コード AL=第一バイト
- ; OUT AX 判定後コード ANK:AH=0
- ; ZERO FLAG AHのTEST結果
- ; 保存レジスタ AX以外
- ;
- ;------------------------------------------------------------------------------
- ;
- chrtypes proc
- ;
- cmp al,081h
- jb chrank
- cmp al,0a0h
- jb chrsjis
- cmp al,0e0h
- jb chrank
- cmp al,0fch
- jbe chrsjis
- chrank:
- xor ah,ah
- ret
- chrsjis:
- xchg ah,al
- test ah,ah
- ret
- ;
- chrtypes endp
- ;
- ;------------------------------------------------------------------------------
- ;
- ; dirlist
- ; 全てのディレクトリ名を検索して、そのパス名をバッファに格納する
- ; ワイルドカード対応 FUNCTION 4EH,4FH
- ;
- ; TYPE near call
- ; IN 検索情報構造体
- ; OUT ディレクションフラグ アップ方向
- ; 保存レジスタ bp,ds
- ;
- ;------------------------------------------------------------------------------
- ;
- dirlist proc uses bx si
- local copysiz,fnamsiz,saveds
- ;
- mov saveds,ds ;DS セーブ
- les di,srchname ;パス名の長さと、最終位置を獲得
- mov cx,0ffffh
- cld
- xor al,al
- repne scasb
- not cx
- dec cx
- mov fnamsiz,cx
- mov di,word ptr srchname
- call pathsep ; パス名中の最後の'\'位置を獲得
- mov copysiz,cx ; バッファへの共通コピーサイズをセット
- mov di,word ptr srchname
- mov dx,es:[di]
- @cbegin
- @case (zf,on) ; セパレータなし
- @if (dx,=,'.'),or,(dx,=,'..') ; カレント/親?
- jmp parentdir
- @ifend
- @case (fnamsiz,=,1),and,(dl,=,'\'),S ; ルート指定か?
- mov ah,19h ; カレントドライブ取得
- int 21h
- add al,'A' ; ドライブ名作成
- mov ah,':'
- jmp rootpath
- @case (cx,=,2),S ; カレント/親 指定か?
- @if (dh,=,':')
- @if (fnamsiz,=,2)
- sub namebuffsiz,4 ; ディレクトリ名バッファサイズチェック
- @if (cf,on)
- add namebuffsiz,4
- jmp srchout
- @ifend
- cld
- les di,namebuff
- mov ax,dx ; ドライブ名
- stosw
- mov ax,'.' ; カレントディレクトリ指定
- stosw
- mov word ptr namebuff,di ; 新オフセット設定
- jmp srchout
- @ifend
- @if (fnamsiz,<=,4)
- mov ax,es:[di+2]
- @if (ax,=,'.'),or,(ax,=,'..')
- jmp parentdir
- @ifend
- @ifend
- @ifend
- @case (fnamsiz,=,3),and,(word ptr es:[di+1],=,'\:'),S ; ルート指定か?
- mov ax,dx
- rootpath:
- sub namebuffsiz,3 ; バッファ残りサイズ確認
- @if (cf,on)
- add namebuffsiz,3
- jmp srchout
- @ifend
- cld
- les di,namebuff ; ドライブ名のみセット
- stosw
- xor al,al
- stosb
- mov word ptr namebuff,di
- jmp srchout
- @cend
- ;
- mov ah,4eh ;最初のファイル名検索ファンクション
- mov cx,037h ;ボリュームラベル以外すべて
- lds dx,srchname
- int 21h
- @do while,(cf,off)
- mov ds,saveds ; DS 復元
- les di,dta
- @if (byte ptr es:[di-9],on,10h) ;ディレクトリかどうかのチェック
- mov dx,es:[di] ; 再帰処理のさいに '.' '..' を外す
- @if (subsearch,=,YES)
- @if (dx,=,'.'),or,(dx,=,'..')
- jmp skipperiod
- @ifend
- @ifend
- mov cx,13 ;DTA上のファイル名から、長さを獲得
- xor al,al
- cld
- repne scasb
- sub cx,13
- neg cx
- mov fnamsiz,cx ;ファイル名長さをセーブ
- add cx,copysiz ;残りバッファサイズのチェックと更新
- sub namebuffsiz,cx
- @if (cf,on)
- add namebuffsiz,cx ;不足
- jmp short srchout
- @ifend
- les di,namebuff ;共通パス名のコピー
- lds si,srchname
- mov cx,copysiz
- rep movsb
- mov ds,saveds ;ファイル名のコピー
- lds si,dta
- mov cx,fnamsiz
- rep movsb
- mov ds,saveds
- mov word ptr namebuff,di ;新オフセットの設定
- @ifend
- skipperiod:
- mov ah,4fh ;次のファイル名検索ファンクション
- lds dx,srchname
- mov cx,037h
- int 21h ;見つかればパス名セーブ
- @doend
- mov ds,saveds
- srchout:
- ret
- ;
- parentdir:
- cld ; パス名長さを調べる
- les di,srchname
- xor ax,ax
- mov cx,-1
- repne scasb
- not cx
- sub namebuffsiz,cx
- @if (cf,on)
- add namebuffsiz,cx ;不足
- jmp short srchout
- @ifend
- les di,namebuff ;ファイル名のコピー
- lds si,srchname
- rep movsb
- mov ds,saveds ; DS 復元
- mov word ptr namebuff,di ;新オフセットの設定
- jmp short srchout
- ;
- dirlist endp
- ;
- ;------------------------------------------------------------------------------
- ;
- ; pathsep
- ; パス名を調べて一番最後の':'か'\'までのバイト数を通知する
- ;
- ; TYPE near call
- ; IN CX パス名長さ
- ; ES:DI パス名の先頭アドレス
- ; OUT CX & ZERO FLAG 最後の':'or'\'までのバイト数 及び 0か?
- ; DIR FLAG アップ方向
- ; 保存レジスタ bx,si,bp,ds,es
- ;
- ;------------------------------------------------------------------------------
- ;
- pathsep proc
- ;
- @if (cx,/=,0) ; 0 でない時
- push cx ; 長さをセーブ
- xor dx,dx ; 位置を初期化
- @do until
- mov al,es:[di] ; 文字獲得
- inc di
- @cbegin
- @case (al,=,':'),or,(al,=,'\'),S ; セパレータならば位置を記憶
- mov dx,cx
- @case (al,<,81h),or,(al,>,0fch),S ; α/N なにもしない
- @case (al,>=,0a0h),and,(al,<=,0dfh),S ; カナ なにもしない
- @other ; 漢字 第二バイト分を進める
- inc di
- dec cx ; 残り0なら終了
- jz analysend
- @cend
- dec cx ; 残り0なら終了
- @doend (zf,on)
- analysend:
- pop cx ; パス名長を復元
- @if (dx,/=,0),S ; セパレータが有った時
- dec dx ; DX にはパス名最後からのオフセット
- sub cx,dx ; 先頭からのオフセットに直す
- @else
- xor cx,cx ; セパレータが無い時は0
- @ifend
- @ifend
- ret
- ;
- pathsep endp
- ;
- ;------------------------------------------------------------------------------
- ;
- ; dirfind
- ; パス名をもとにディレクトリかを調べ、ディレクトリの開始クラスタ
- ; と、存在するドライブ番号を通知する
- ;
- ; TYPE near call
- ; IN ES:DI パス名の先頭アドレス
- ; OUT AX ディレクトリの開始クラスタ番号
- ; DL ドライブ番号
- ; CARRY FLAG ディレクトリ属性 0:DIR 1:OTHERまたはルートでファイル無し
- ; 保存レジスタ bp,ds
- ;
- ;------------------------------------------------------------------------------
- ;
- dirfind proc
- ;
- call strcopywild ; 検索用パス名の作成
- ;
- mov ah,2fh ; DTA 取得
- int 21h
- ;
- mov ah,4eh ; ファイル検索
- mov cx,3fh
- int 21h
- @if (cf,off) ; 見つかった
- mov ax,es:[bx+0fh] ; ディレクトリの開始クラスタ取得
- xor dx,dx
- mov dl,es:[bx] ; ディレクトリのドライブ番号取得
- @ifend
- ret
- ;
- dirfind endp
- ;
- ;------------------------------------------------------------------------------
- ;
- ; strcopywild
- ; 指定されたパス名をPATHBUFFにコピーし、ワイルドカードを付加する
- ;
- ; TYPE near call
- ; IN ES:DI パス名の先頭アドレス
- ; OUT PATHBUFF
- ; ES:DI PATHBUFFのアドレス
- ; 保存レジスタ bp,ds
- ;
- ;------------------------------------------------------------------------------
- ;
- strcopywild proc
- ;
- cld ; パス名長さを調べる
- mov cx,-1
- xor ax,ax
- mov si,di
- repne scasb
- not cx
- dec cx
- mov ax,ds ; パス名をPATHBUFFにコピー
- mov dx,es
- mov ds,dx
- mov es,ax
- mov di,offset pathbuff
- mov dx,di
- rep movsb
- mov ds,ax ; ワイルドカード指定を付加
- mov cx,5
- mov si,offset wildcard
- rep movsb
- ;
- mov di,offset pathbuff
- ret
- ;
- strcopywild endp
- ;
- end